
import maya.cmds as cmds
import AntsCrowd.transform as transform
import AntsCrowd.Terrain as Terrain
import AntsCrowd.Simulator as Simulator
import AntsCrowd.AutoWalk as AutoWalk
import AntsCrowd.Agent as Agent
import glob
import time
import random

reload(transform)
reload(Terrain)
reload(Simulator)
reload(AutoWalk)
reload(Agent)

mode = 'instance'
divTime = 3
terrain_mode = 1
checkheight = 0

def runProc(grd = 100 , ants = 10 , maxTime = 240 , mode = 'high' , divTime = 1 ,
            terrain_mode = 1 , checkheight = 0, agentMode = 'wander'  ):
    '''
    _____________________________________________________________
    
        Parameter Description
        
        Model Quality
        - low, middle, high
        
        Terrain Mode
        - Height On / Off
        
        CheckHeight
        - 1: RayIntersection, 0: HeightMap
    _____________________________________________________________
    '''
    
    random.seed()
    
    # New Scene (clear previous state)
    cmds.file( mf = False)
    cmds.file( f = True, new = True )
    
    # find all model filename
    #_low - low model is cube
    Model.lowModel = glob.glob( r"X:\Works\3d\ant\model\Ants_female56_*.mb" )[-1]
    Model.highModel = glob.glob( r"X:\Works\3d\ant\rig\newant_ac_rig_*.mb" )[-1]
    
    cmds.file( Model.lowModel, i = True, ra = False )
    cmds.file( Model.highModel, i = True, ra = False )
    
    # initialize timer
    try :
        cmds.timer( s=True ,lap=1,name= 'tester' )
    except :
        cmds.timer( e=True ,name= 'tester')
        cmds.timer( s=True ,lap=1,name= 'tester' )
    print '\n\nProcess start\n',time.ctime(), '\n\n'
    
    ## Import Camera
    camFileList = [ r"X:\Works\3d\ant\cam\antCrowd_20_grd.mb" ,
                   r"X:\Works\3d\ant\cam\antCrowd_50_grd.mb" ,
                   r"X:\Works\3d\ant\cam\antCrowd_100_grd.mb" ]
    if grd < 50 :
        camFile = camFileList[0]
    elif grd >= 50 and grd < 100:
        camFile = camFileList[1]
    else :
        camFile = camFileList[2]
    
    cmds.file(camFile , i=1 , ra=0)
    
    
    if terrain_mode:
        _Terrain = Terrain.Terrain( r"\\192.168.131.222\kali\Project\AntsCrowd\Resource\heightmap.jpg" , grd )
        #_Terrain = Terrain.Terrain( r"X:\_temp\ground_Depth.jpg" , grd )
    else:
        _Terrain = Terrain.Terrain( None , grd )
    if mode == 'LOD' :
        _ModelList =  _Terrain.fnCreateLODAnts( 'ant_all' , ants )
    elif mode == 'NULL' :
        _ModelList =  _Terrain.fnCreateNull( ants )
    elif mode == 'cube' :
        _ModelList = _Terrain.fnCreateCube( ants ) 
    elif mode == 'instance':
        _ModelList =  _Terrain.fnCreateModel( 'ant_mid_all' , ants, 1, agentMode ) 
    elif mode =='high':
        _ModelList =  _Terrain.fnCreateModel( 'ant_all' , ants , 0 )
        
    _ObstacleList = _Terrain.fnCreateObstacle( 0 )
    
    print 'CreateModel'    
    cmds.viewFit()
    cmds.select(cl=1)    
    
    cmds.playbackOptions( maxTime = maxTime )
    cmds.playbackOptions( minTime = 0 )
    
    _Simulator = Simulator.Simulator()
    
    for _mod in _ModelList :
        if mode == 'instance' :
            #instance
            _ModelX = cmds.getAttr( _mod[0] + '.translateX' )
            _ModelY = cmds.getAttr( _mod[0] + '.translateZ' )
            
        else :            
            # duplicate        
            print _mod['main']
            _ModelX = cmds.getAttr( _mod['main'][0] + '.translateX' )
            _ModelY = cmds.getAttr( _mod['main'][0] + '.translateZ' )
            
        _agent = _Simulator.fnAddAgent( FCVector.vector2D( _ModelX , _ModelY ), 25, agentMode )
        
        if agentMode == 'goal':
            _goalX = random.uniform( _Terrain.mTerrainWidth / 2 - 100, _Terrain.mTerrainWidth / 3 - 100 )
            _goalZ = random.uniform( _Terrain.mTerrainHeight / 2 - 100, _Terrain.mTerrainHeight/ 3 - 100 )
            _agent.setGoal( -_goalX, -_goalZ )
       
    print 'AddAgent'
     
    for _Idx in xrange( len( _ObstacleList )):
        _ObstacleX = cmds.getAttr( _ObstacleList[_Idx][0] + '.translateX' )
        _ObstacleY = cmds.getAttr( _ObstacleList[_Idx][0] + '.translateZ' )
        _Radius = cmds.getAttr( _ObstacleList[_Idx][1] + '.width' )/2
        _Simulator.fnAddObstacle( FCVector.vector2D( _ObstacleX, _ObstacleY ), _Radius )   

    for _TimeCnt in xrange( maxTime + 1 ):        
        
        _Simulator.fnProcessObstacles()
        #_Simulator.fnPreferredAgent()
        StepValue = 24.0
        _Simulator.fnDoStep( 1.0 / StepValue )

        if _TimeCnt % divTime != 0 :
            continue
        
        for _Idx in xrange( len(_Simulator.mAgentList) ):
            _PosX = _Simulator.mAgentList[_Idx].mPosition.x
            _PosZ = _Simulator.mAgentList[_Idx].mPosition.y
            _Angle = transform.RadianToDegree( _Simulator.mAgentList[_Idx].mAngle )
            _Head = transform.vec2Dnormalize( _Simulator.mAgentList[_Idx].mVelocity )
           
            #_Head = _Simulator.mAgentList[_Idx].mHeading
            _info = []
            if terrain_mode :	
                if checkheight: 
                    _info = _Terrain.fnGetXZRotateAndHeight(_PosX,1000,_PosZ,_Head)    
                else:
                    _info = _Terrain.fnGetInfo(_PosX,_PosZ,_Head) 
                _RotX = transform.RadianToDegree(_info[0])  
                _RotY = transform.RadianToDegree(_info[1])          
                _RotZ = transform.RadianToDegree(_info[2]) 
                _PosY = _info[3]
 
            if mode == 'instance' :
                # instance
                if terrain_mode  : 
                    cmds.setKeyframe( _ModelList[_Idx][0], attribute = 'rotateX', value = _RotX, t = _TimeCnt ) 
                    cmds.setKeyframe( _ModelList[_Idx][0], attribute = 'rotateZ', value = _RotZ, t = _TimeCnt ) 
                    cmds.setKeyframe( _ModelList[_Idx][0], attribute = 'translateY', value = _PosY, t = _TimeCnt )            
                    cmds.setKeyframe( _ModelList[_Idx][0], attribute = 'rotateY', value = _Angle, t = _TimeCnt )
                else:
                    cmds.setKeyframe( _ModelList[_Idx][0], attribute = 'rotateY', value = _Angle, t = _TimeCnt ) 
                cmds.setKeyframe( _ModelList[_Idx][0], attribute = 'translateX', value = _PosX, t = _TimeCnt )
                cmds.setKeyframe( _ModelList[_Idx][0], attribute = 'translateZ', value = _PosZ, t = _TimeCnt )
 
            else :
                #duplicate                         
                cmds.currentTime( _TimeCnt )

                cmds.setKeyframe( _ModelList[_Idx]['main'][0], attribute = 'translateX', value = _PosX )
                cmds.setKeyframe( _ModelList[_Idx]['main'][0], attribute = 'translateZ', value = _PosZ )                
                cmds.setKeyframe( _ModelList[_Idx]['main'][0], attribute = 'rotateY', value = _Angle )
                if terrain_mode : 
                    cmds.setKeyframe( _ModelList[_Idx]['main'][0], attribute = 'translateY', value = _PosY  )
                    cmds.setKeyframe( _ModelList[_Idx]['main'][0], attribute = 'rotateX', value = _RotX )
                    cmds.setKeyframe( _ModelList[_Idx]['main'][0], attribute = 'rotateZ', value = _RotZ )
    
        print str(_TimeCnt) + ' Frame';
    
    if mode == 'high' or mode == 'LOD':
        #for frame in xrange( maxTime + 1 ):
        #    cmds.currentTime( frame )
        #    for idx in xrange( len(_antWalkList) ):
        #        _antWalkList[idx].update( frame )
    
        for _Idx in xrange( len(_Simulator.mAgentList) ):
            _Speed = _Simulator.mAgentList[_Idx].getSpeed()
            cmds.currentTime( _TimeCnt )
            
            AutoWalk.upSpeed = 20 / (_Speed / 100 )
            AutoWalk.antwalk( _ModelList[_Idx], walkFreq = 10 / (_Speed / 100 ) ,  maxTime = maxTime )
        
    
    processtime = cmds.timer( e=True ,name= 'tester')    
    print "Process Completed: " , processtime / 60 , 'min'
    
    ## set MAYA up
    cmds.setAttr( "perspShape.farClipPlane" , 1000000 )
    cmds.workspace( cr =  r'X:\Works\3d\ant\antProject' )
    cmds.workspace( r'X:\Works\3d\ant\antProject' , o = 1 )
    cmds.DisplayShaded()
    if ants < 500 :
        cmds.viewFit()
    
    if ants > 500 :
        currentPannel = cmds.getPanel( wf=1 )
        cmds.modelEditor( currentPannel , e=1 , 
                    ikHandles = 0 ,
                    joints = 0 ,
                    nurbsCurves = 0 )
    
    filelist = glob.glob(r'X:\Works\3d\ant\antProject\scenes\*.m*')
    sceneVer = '01' if filelist == [] else filelist[-1].split('_')[-1].split('.')[0]
    cmds.file( rename='antCrowd_'+str( ants ) + '_' + sceneVer + '.ma' )
    
    #cmds.delete('pPlane1')
    
    
if __name__ == "__main__" :
    runProc()   